import os.path

import cv2
import numpy as np


class Processor:
    def __init__(self, config):
        self.config = config['detection']

    def detector_point_threshold(self, img):
        data = []

        # 灰度图
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # 二值化处理
        _, binary_image = cv2.threshold(
            img,
            self.config['binary_threshold']['thresh'],
            self.config['binary_threshold']['maxval'],
            cv2.THRESH_BINARY_INV
        )

        # 形态学操作
        kernel = np.ones((3, 3), np.uint8)
        binary_image = cv2.morphologyEx(binary_image, cv2.MORPH_OPEN, kernel)

        # 连通域分析
        num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary_image, connectivity=8)

        labels = labels.astype(np.uint8)

        # 绘制检测到的黑色点
        for i in range(1, num_labels):
            x, y, w, h, area = stats[i]
            if area < self.config['filter_num']:  # 过滤掉小区域
                data.append({'mask': np.where(labels == i, True, False).astype(np.uint8), 'centroid': centroids[i]})

        return data

    def detector_point_hough(self, image_original):
        data = []
        image = cv2.cvtColor(image_original, cv2.COLOR_BGR2GRAY)

        # 霍夫圆变换检测圆圈
        circles = cv2.HoughCircles(
            image,
            cv2.HOUGH_GRADIENT,  # 使用霍夫梯度方法
            dp=self.config['hough']['dp'],  # 反霍夫变换的分辨率，1表示与输入图像的分辨率相同
            minDist=self.config['hough']['minDist'],  # 检测到的圆圈之间的最小距离
            param1=self.config['hough']['param1'],  # Canny边缘检测的高阈值
            param2=self.config['hough']['param2'],  # 霍夫变换的累加器阈值，越小检测到的圆圈越多，越大检测到的圆圈越少
            minRadius=self.config['hough']['minRadius'],  # 圆圈的最小半径
            maxRadius=self.config['hough']['maxRadius']  # 圆圈的最大半径
        )

        # 如果检测到了圆圈
        if circles is not None:
            circles = np.uint16(np.around(circles))  # 将圆圈坐标和半径转换为整数
            for circle in circles[0, :]:
                center = (circle[0], circle[1])  # 圆心坐标
                data.append({'mask': None, 'centroid': center})
        return data


    @staticmethod
    def show(img, is_save=False, path=None, name=''):
        if is_save:
            assert path, 'path is empty'
            cv2.imwrite(os.path.join(path, ''.join([name, '.jpg'])), img)
        cv2.imshow(name, img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

    @staticmethod
    def show_disparity_image(img, disparity, is_save=False, path=None, name=None):
        # 将视差图转换为伪彩色图像
        disparity_color = cv2.applyColorMap(cv2.normalize(disparity, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8),
                                            cv2.COLORMAP_JET)

        # 将原图转换为彩色（如果它是灰度图）
        if len(img.shape) == 2:
            img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

        # 融合视差图和彩色原图
        alpha = 0.8  # 视差图的权重
        beta = 0.2  # 原图的权重
        blended_image = cv2.addWeighted(img, beta, disparity_color, alpha, 0)

        # 显示融合图像
        cv2.imshow(name, blended_image)
        if is_save:
            assert path, 'path is empty'
            cv2.imwrite(os.path.join(path, ''.join([name, '.jpg'])), blended_image)
        cv2.waitKey()
        cv2.destroyAllWindows()

    @staticmethod
    def show_center_point(img, masks_centroid_left):
        for data in masks_centroid_left:
            centroid = (int(data['centroid'][0]), int(data['centroid'][1]))
            cv2.circle(img, centroid, radius=1, color=(0, 0, 255), thickness=1)
        cv2.imshow('', img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
